import 'dart:math';

const double F_MAX = 20000.0;
const double F_MIN = 20.0;
const double F = 48000.0;
const double R = 6.283185307179586;

///DSP 核心算法
class EQUtil {
  ///将自然对数转换成了 以 10 为底的对数。
  ///用于计算任意数字的 以 10 为底的对数。
  static double _log10(double x) {
    return log(x) / log(10);
  }

  /// 把频率值，映射到某个线性范围内的整数值上。
  /// - Parameters:
  ///   - frency: 频率
  ///   - width: 相位画布的宽度，即范围
  /// - Returns: 映射后的整数
  static double toInt(double frency, double width) {
    final double f = _log10(22000.0) - _log10(20.0);
    final double f1 = _log10(frency) - _log10(20.0);
    return f1 / f * width;
  }

  /// 把线性范围内的整数值，映射到频率上
  /// - Parameters:
  ///   - v: 需要映射的值
  ///   - v_max: 整数线性范围的最大值
  ///   - v_min: 整数线性范围的最小值
  /// - Returns: 频率
  static double deInt(int v, int v_max, int v_min, {double f_max = 22000.0}) {
    final double s_v = (v - v_min) / (v_max - v_min).toDouble();
    final double f = _log10(f_max) - _log10(20.0);
    double result = pow(10.0, s_v * f + _log10(20.0)).toDouble();
    return result;
  }

  ///1， PEQ特性点增益值算法
  static void eq(double quality, double gain, double frency, List<double> array) {
    final num var0 = pow(10.0, gain / 40.0);
    final double var1 = R * frency / F;
    final double var2 = sin(var1) / (2 * quality);
    final double var3 = var2 / var0;
    final double var4 = -2.0 * cos(var1);
    final double var5 = 1.0 - var2 / var0;
    final double var6 = -2.0 * cos(var1);
    final double var7 = (1.0 - var2 * var0) * 1.0;
    final double negVar6 = -var6;
    final double negVar4 = -var4;

    for (int i = 0; i < array.length; i++) {
      final num f = deInt(i, array.length, 0);
      final double var10 = R * f / F;
      final double cosVar10 = cos(var10);
      final double cos2Var10 = cos(2.0 * var10);
      final double sinVar10 = sin(var10);
      final double sin2Var10 = sin(2.0 * var10);

      final double term1 = cosVar10 * var6 + (1.0 + var2 * var0) * 1.0 + cos2Var10 * var7;
      final double term2 = negVar6 * sinVar10 - sin2Var10 * var7;
      final double term3 = cosVar10 * var4 + 1.0 + var3 + cos2Var10 * var5;
      final double term4 = negVar4 * sinVar10 - sin2Var10 * var5;

      final num numerator = pow(term1, 2.0) + pow(term2, 2.0);
      final num denominator = pow(term3, 2.0) + pow(term4, 2.0);

      final double sqrtValue = sqrt(numerator / denominator);
      array[i] = _log10(sqrtValue);
    }
  }

  /// 计算滤波器的相位响应或幅值响应，并将结果存储在`one`数组中。
  static void _mk(List<double> a, List<double> b, List<double> one, bool ispol) {
    final int len = one.length;
    double x, w, u, v, s, t, h;

    for (int i = 0; i < len; i++) {
      x = deInt(i, len, 0, f_max: F_MAX).toDouble();
      w = 2 * pi * x / F;

      u = b[0] + b[1] * cos(w) + b[2] * cos(2 * w);
      v = -b[1] * sin(w) - b[2] * sin(2 * w);

      s = a[0] + a[1] * cos(w) + a[2] * cos(2 * w);
      t = -a[1] * sin(w) - a[2] * sin(2 * w);

      if (ispol) {
        final double Im = (s * v - t * u);
        final double Re = (s * u + t * v);
        h = 180 * atan2(Im, Re) / pi;
      } else {
        h = sqrt((pow(u, 2) + pow(v, 2)) / (pow(s, 2) + pow(t, 2)));
        h = _log10(h);
      }

      one[i] = h;
    }
  }

  /// 创建一个包含指定数量零的数组。
  static List<double> _getArray(int count) {
    return List<double>.filled(count, 0.0);
  }

  ///2，高低通，滤波算法
  static List<double> filter(double f, int octType, bool ishpass, bool bypass, List<double> array) {
    var p = _getArray(4);
    var a0 = _getArray(3);
    var a1 = _getArray(3);
    var a2 = _getArray(3);
    var a3 = _getArray(3);
    var b0 = _getArray(3);
    var b1 = _getArray(3);
    var b2 = _getArray(3);
    var b3 = _getArray(3);

    var one_0 = _getArray(array.length);
    var one_1 = _getArray(array.length);
    var one_2 = _getArray(array.length);
    var one_3 = _getArray(array.length);
    // 计算角频率
    double w0 = 2 * pi * f / F;
    double oc = 2 * tan(w0 / 2);
    double c1 = oc * tan(w0 / 2);

    bool iszero = (f == F_MAX && !ishpass) || (f == F_MIN && ishpass) || bypass;
    if (iszero) {
      array.fillRange(0, array.length, 0.0);
      return array;
    }

    switch (octType) {
      case 0: // BW-06
        p[0] = ishpass ? 1 : 0;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass ? ((c1 - p[0] * oc) / (c1 + p[0] * oc)) : (oc - 2) / (oc + 2);
        a0[2] = ishpass ? 0 : 0;

        b0[0] = ishpass ? (oc / (c1 + p[0] * oc)) : oc / (2 + oc);
        b0[1] = ishpass ? -b0[0] : b0[0];
        b0[2] = ishpass ? 0 : 0;

        _mk(a0, b0, one_0, false);
        array = iszero ? _getArray(array.length) : one_0;
      case 1: // BW-12
        p[0] = ishpass ? 1.41421356237309 : 1.41421356237309;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : 2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc);
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc);

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : oc * oc / (4 + 2 * p[0] * oc + oc * oc);
        b0[1] = ishpass ? -2 * b0[0] : 2 * b0[0];
        b0[2] = ishpass ? b0[0] : b0[0];

        _mk(a0, b0, one_0, false);
        array = iszero ? _getArray(array.length) : one_0;
      case 2: // BW-18
        p[0] = ishpass ? 1 : 1;
        p[1] = ishpass ? 1 : 1;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass ? (-(p[1] * oc - c1) / (c1 + p[1] * oc)) : ((p[1] * oc - 2) / (2 + p[1] * oc));
        a1[2] = ishpass ? 0 : 0;

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? -2 * b0[0] : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (p[1] * oc / (c1 + p[1] * oc)) : (p[1] * oc / (2 + p[1] * oc));
        b1[1] = ishpass ? -b1[0] : b1[0];
        b1[2] = ishpass ? 0 : 0;

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        array = iszero ? _getArray(array.length) : List.generate(array.length, (i) => one_0[i] + one_1[i]);
      case 3: // BW-24
        p[0] = ishpass ? 0.76536686473018 : 0.76536686473018;
        p[1] = ishpass ? 1.84775906502257 : 1.84775906502257;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        array = iszero ? _getArray(array.length) : List.generate(array.length, (i) => one_0[i] + one_1[i]);

      case 4: // BW-36
        p[0] = ishpass ? 0.51763809020504 : 0.51763809020504;
        p[1] = ishpass ? 1.41421356237309 : 1.41421356237309;
        p[2] = ishpass ? 1.93185165257814 : 1.93185165257814;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? 1 : 1;
        a2[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc));
        a2[2] = ishpass
            ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc));
        b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0]);
        b2[2] = ishpass ? b2[0] : b2[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        array = iszero ? _getArray(array.length) : List.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i]);

      case 5: // BW-48
        p[0] = ishpass ? 0.39018064403226 : 0.39018064403226;
        p[1] = ishpass ? 1.11114046603920 : 1.11114046603920;
        p[2] = ishpass ? 1.66293922460509 : 1.66293922460509;
        p[3] = ishpass ? 1.96157056080646 : 1.96157056080646;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? 1 : 1;
        a2[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc));
        a2[2] = ishpass
            ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc));

        a3[0] = ishpass ? 1 : 1;
        a3[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[3] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[3] * oc + oc * oc));
        a3[2] = ishpass
            ? ((c1 * c1 - c1 * p[3] * oc + oc * oc) / (c1 * c1 + c1 * p[3] * oc + oc * oc))
            : ((4 - 2 * p[3] * oc + oc * oc) / (4 + 2 * p[3] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc));
        b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0]);
        b2[2] = ishpass ? b2[0] : b2[0];

        b3[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[3] * oc + oc * oc));
        b3[1] = ishpass ? (-2 * b3[0]) : (2 * b3[0]);
        b3[2] = ishpass ? b3[0] : b3[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        _mk(a3, b3, one_3, false);
        array = iszero
            ? _getArray(array.length)
            : List.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i] + one_3[i]);
      case 6: // BS-12
        p[0] = ishpass ? 1.73205080756888 : 1.73205080756888;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        var one_0 = _getArray(array.length);
        _mk(a0, b0, one_0, false);
        array = iszero ? _getArray(array.length) : one_0;

      case 7: // BS-18
        p[0] = ishpass ? 1.49128077169616 : 1.49128077169616;
        p[1] = ishpass ? 0.94160002653321 : 0.94160002653321;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass ? (-(p[1] * oc - c1) / (c1 + p[1] * oc)) : ((p[1] * oc - 2) / (2 + p[1] * oc));
        a1[2] = ishpass ? 0 : 0;

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (p[1] * oc / (c1 + p[1] * oc)) : (p[1] * oc / (2 + p[1] * oc));
        b1[1] = ishpass ? (-b1[0]) : b1[0];
        b1[2] = ishpass ? 0 : 0;

        array = iszero ? _getArray(array.length) : List<double>.generate(array.length, (i) => one_0[i] + one_1[i]);

      case 8: // BS-24
        p[0] = ishpass ? 1.31442234334377 : 1.31442234334377;
        p[1] = ishpass ? 1.80951759357649 : 1.80951759357649;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        array = iszero ? _getArray(array.length) : List<double>.generate(array.length, (i) => one_0[i] + one_1[i]);

      case 9: // BS-36
        p[0] = ishpass ? 1.81878136609445 : 1.81878136609445;
        p[1] = ishpass ? 1.59930837166566 : 1.59930837166566;
        p[2] = ishpass ? 1.07710536333862 : 1.07710536333862;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? 1 : 1;
        a2[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc));
        a2[2] = ishpass
            ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc));
        b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0]);
        b2[2] = ishpass ? b2[0] : b2[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        array = iszero
            ? _getArray(array.length)
            : List<double>.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i]);
      case 10: // BS-48
        p[0] = ishpass ? 1.81936630933058 : 1.81936630933058;
        p[1] = ishpass ? 1.69465016047187 : 1.69465016047187;
        p[2] = ishpass ? 1.42227636169708 : 1.42227636169708;
        p[3] = ishpass ? 0.92434808250642 : 0.92434808250642;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? 1 : 1;
        a2[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc));
        a2[2] = ishpass
            ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc));

        a3[0] = ishpass ? 1 : 1;
        a3[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[3] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[3] * oc + oc * oc));
        a3[2] = ishpass
            ? ((c1 * c1 - c1 * p[3] * oc + oc * oc) / (c1 * c1 + c1 * p[3] * oc + oc * oc))
            : ((4 - 2 * p[3] * oc + oc * oc) / (4 + 2 * p[3] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc));
        b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0]);
        b2[2] = ishpass ? b2[0] : b2[0];

        b3[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[3] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[3] * oc + oc * oc));
        b3[1] = ishpass ? (-2 * b3[0]) : (2 * b3[0]);
        b3[2] = ishpass ? b3[0] : b3[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        _mk(a3, b3, one_3, false);
        array = iszero
            ? _getArray(array.length)
            : List<double>.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i] + one_3[i]);
      case 11: // LK-12
        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass ? (-(oc - c1) / (c1 + oc)) : ((oc - 2) / (2 + oc));
        a0[2] = ishpass ? 0 : 0;

        a1[0] = ishpass ? a0[0] : a0[0];
        a1[1] = ishpass ? a0[1] : a0[1];
        a1[2] = ishpass ? a0[2] : a0[2];

        b0[0] = ishpass ? (oc / (c1 + oc)) : (oc / (2 + oc));
        b0[1] = ishpass ? (-b0[0]) : b0[0];
        b0[2] = ishpass ? 0 : 0;

        b1[0] = ishpass ? b0[0] : b0[0];
        b1[1] = ishpass ? b0[1] : b0[1];
        b1[2] = ishpass ? b0[2] : b0[2];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        array = iszero ? _getArray(array.length) : List<double>.generate(array.length, (i) => one_0[i] + one_1[i]);
      case 12: // LK-24
        p[0] = ishpass ? 1.41421356237309 : 1.41421356237309;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? a0[0] : a0[0];
        a1[1] = ishpass ? a0[1] : a0[1];
        a1[2] = ishpass ? a0[2] : a0[2];

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? b0[0] : b0[0];
        b1[1] = ishpass ? b0[1] : b0[1];
        b1[2] = ishpass ? b0[2] : b0[2];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        array = iszero ? _getArray(array.length) : List<double>.generate(array.length, (i) => one_0[i] + one_1[i]);

      case 13: // LK-36
        p[0] = ishpass ? 0.76536686473018 : 0.76536686473018;
        p[1] = ishpass ? 1.84775906502257 : 1.84775906502257;
        p[2] = ishpass ? 1.41421356237309 : 1.41421356237309;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? 1 : 1;
        a2[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[2] * oc + oc * oc));
        a2[2] = ishpass
            ? ((c1 * c1 - c1 * p[2] * oc + oc * oc) / (c1 * c1 + c1 * p[2] * oc + oc * oc))
            : ((4 - 2 * p[2] * oc + oc * oc) / (4 + 2 * p[2] * oc + oc * oc));

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[2] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[2] * oc + oc * oc));
        b2[1] = ishpass ? (-2 * b2[0]) : (2 * b2[0]);
        b2[2] = ishpass ? b2[0] : b2[0];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        array = iszero
            ? _getArray(array.length)
            : List<double>.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i]);
      case 14: // LK-48
        p[0] = ishpass ? 0.76536686473018 : 0.76536686473018;
        p[1] = ishpass ? 1.84775906502257 : 1.84775906502257;

        a0[0] = ishpass ? 1 : 1;
        a0[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[0] * oc + oc * oc));
        a0[2] = ishpass
            ? ((c1 * c1 - c1 * p[0] * oc + oc * oc) / (c1 * c1 + c1 * p[0] * oc + oc * oc))
            : ((4 - 2 * p[0] * oc + oc * oc) / (4 + 2 * p[0] * oc + oc * oc));

        a1[0] = ishpass ? 1 : 1;
        a1[1] = ishpass
            ? (-2 * (oc * oc - c1 * c1) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : (2 * (oc * oc - 4) / (4 + 2 * p[1] * oc + oc * oc));
        a1[2] = ishpass
            ? ((c1 * c1 - c1 * p[1] * oc + oc * oc) / (c1 * c1 + c1 * p[1] * oc + oc * oc))
            : ((4 - 2 * p[1] * oc + oc * oc) / (4 + 2 * p[1] * oc + oc * oc));

        a2[0] = ishpass ? a0[0] : a0[0];
        a2[1] = ishpass ? a0[1] : a0[1];
        a2[2] = ishpass ? a0[2] : a0[2];

        a3[0] = ishpass ? a1[0] : a1[0];
        a3[1] = ishpass ? a1[1] : a1[1];
        a3[2] = ishpass ? a1[2] : a1[2];

        b0[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[0] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[0] * oc + oc * oc));
        b0[1] = ishpass ? (-2 * b0[0]) : (2 * b0[0]);
        b0[2] = ishpass ? b0[0] : b0[0];

        b1[0] = ishpass ? (oc * oc / (c1 * c1 + c1 * p[1] * oc + oc * oc)) : (oc * oc / (4 + 2 * p[1] * oc + oc * oc));
        b1[1] = ishpass ? (-2 * b1[0]) : (2 * b1[0]);
        b1[2] = ishpass ? b1[0] : b1[0];

        b2[0] = ishpass ? b0[0] : b0[0];
        b2[1] = ishpass ? b0[1] : b0[1];
        b2[2] = ishpass ? b0[2] : b0[2];

        b3[0] = ishpass ? b1[0] : b1[0];
        b3[1] = ishpass ? b1[1] : b1[1];
        b3[2] = ishpass ? b1[2] : b1[2];

        _mk(a0, b0, one_0, false);
        _mk(a1, b1, one_1, false);
        _mk(a2, b2, one_2, false);
        _mk(a3, b3, one_3, false);

        array = iszero
            ? _getArray(array.length)
            : List<double>.generate(array.length, (i) => one_0[i] + one_1[i] + one_2[i] + one_3[i]);
      default:
        break;
    }
    return array;
  }
}
